package org.example;

import lombok.Getter;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.StringJoiner;

public class FillNameForm {
    private static final String NAME_DELIMITER = " ";
    private static final String NAME_VALID_CHARS = "\\p{IsAlpha}-";
    private static final String NAME_PATTERN = "\\p{IsAlpha}[" + NAME_VALID_CHARS + "]*";
    private static final String INVALID_CHAR_ERROR = "Недопустимый символ в имени";
    private static final String INVALID_FORMAT_ERROR = "Недопустимый формат имени";
    private static final String NO_NAME_ERROR = "Нет имени или фамилии";

    @Getter
    private JPanel panel;
    private JPanel collapsePanel;
    private JPanel expandPanel;
    private JTextField surnameTextField;
    private JTextField nameTextField;
    private JTextField fullNameTextField;
    @Getter
    private JButton expandButton;
    @Getter
    private JButton collapseButton;
    private JPanel cardPanel;
    private JTextField patronymicTextField;
    private JLabel fullNameLabel;
    private JLabel surnameLabel;
    private JLabel nameLabel;
    private JLabel patronymicLabel;
    private JLabel collapseErrorLabel;
    private JLabel expandErrorLabel;

    FillNameForm () {
        collapseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formatName(surnameTextField);
                formatName(nameTextField);
                formatName(patronymicTextField);

                String error = checkName(surnameTextField);
                if (error == null) {
                    error = checkName(nameTextField);
                }
                if (error == null) {
                    error = checkName(patronymicTextField);
                    if (" ".equals(error)) {    // Not required field
                        error = null;
                    }
                }

                collapseErrorLabel.setText(error == null ? " " : error);

                if (error != null) {
                    return;
                }

                fullNameTextField.setText(
                        surnameTextField.getText() + NAME_DELIMITER +
                        nameTextField.getText() + NAME_DELIMITER +
                        patronymicTextField.getText()
                );
                formatName(fullNameTextField);

                expandPanel.setVisible(true);
                collapsePanel.setVisible(false);
                Main.frame.getRootPane().setDefaultButton(getExpandButton());

                fullNameTextField.requestFocus();
                fullNameTextField.selectAll();
            }
        });

        expandButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                formatName(fullNameTextField);

                if (fullNameTextField.getText().isEmpty()) {
                    fullNameTextField.requestFocus();

                    expandErrorLabel.setText(" ");

                    return;
                }

                String[] names = fullNameTextField.getText().split(NAME_DELIMITER);
                if (names.length < 2) {
                    fullNameTextField.requestFocus();
                    fullNameTextField.selectAll();

                    expandErrorLabel.setText(NO_NAME_ERROR);

                    return;
                }

                names[0] = formatName(names[0]);
                String error = checkName(names[0]);
                if (error == null) {
                    names[1] = formatName(names[1]);
                    error = checkName(names[1]);
                }
                if (error == null && names.length > 2) {
                    names[2] = formatName(names[2]);
                    error = checkName(names[2]);
                    if (" ".equals(error)) {    // Not required field
                        error = null;
                    }
                }

                expandErrorLabel.setText(
                        error == null ? " " : (
                                " ".equals(error) ? NO_NAME_ERROR : error
                        )
                );

                if (error != null) {
                    fullNameTextField.requestFocus();
                    fullNameTextField.selectAll();

                    return;
                }

                surnameTextField.setText(names[0]);
                nameTextField.setText(names[1]);
                patronymicTextField.setText(names.length > 2 ? names[2] : "");

                collapsePanel.setVisible(true);
                expandPanel.setVisible(false);
                Main.frame.getRootPane().setDefaultButton(getCollapseButton());

                surnameTextField.requestFocus();
                surnameTextField.selectAll();
            }
        });
    }

    private String checkName(JTextComponent component) {
        String error = checkName(component.getText());

        if (error != null) {
            component.requestFocus();
            component.selectAll();
        }

        return error;
    }

    private String checkName(String text) {
        if (!text.matches(NAME_PATTERN)) {
            if (!text.isEmpty()) {
                String invalidChars = text.replaceAll("[" + NAME_VALID_CHARS + "]", "");

                if (!invalidChars.isEmpty()) {
                    return INVALID_CHAR_ERROR + ": '" + invalidChars + "'";
                } else {
                    return INVALID_FORMAT_ERROR;
                }
            }

            return " ";     // Empty field
        }

        return null;        // Correct field
    }

    private void formatName(JTextComponent component) {
        component.setText(formatName(component.getText()));
    }

    private String formatName(String text) {
        StringJoiner stringJoiner = new StringJoiner(NAME_DELIMITER);
        String[] words = text
                .trim()
                .replaceAll("\\s+", NAME_DELIMITER)
                .replaceAll("\\s*-+\\s*", "-")
                .replaceAll("^[-" + NAME_DELIMITER + "]+", "")
                .replaceAll("[-" + NAME_DELIMITER + "]+$", "")
                .replaceAll("[^" + NAME_VALID_CHARS + NAME_DELIMITER + "]", "")
                .split(NAME_DELIMITER);

        for (String word : words) {
            if (word.isEmpty()) {
                continue;
            }

            word = word.toLowerCase()
                .replaceFirst(".",
                        word.substring(0, 1).toUpperCase()
                );

            String[] parts = word.split("-");
            if (parts.length == 0) {
                continue;
            }

            for (int i = 1; i < parts.length; i++) {
                parts[0] = parts[0].concat("-").concat(
                        parts[i].replaceFirst(".",
                                parts[i].substring(0, 1).toUpperCase()
                        )
                );
            }

            stringJoiner.add(parts[0]);
        }

        return stringJoiner.toString();
    }
}
